package cn.gyouzhe.config;

import cn.gyouzhe.config.props.DBProperties;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.*;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;

import java.util.Properties;

/**
 * 持久层配置
 *
 * @author wangchuan
 * @createTime 2018/2/24 17:42
 */
@Configuration
@EnableTransactionManagement
@Slf4j
public class OrmConfig implements TransactionManagementConfigurer{
    /**
     * 数据库信息
     */
    @Autowired
    private DBProperties props;


    @Bean
    public ServletRegistrationBean DruidStatViewServlet() {
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        servletRegistrationBean.addInitParameter("loginUsername", "pytadmin");
        servletRegistrationBean.addInitParameter("loginPassword", "123456");
        servletRegistrationBean.addInitParameter("resetEnable", "false");
        return servletRegistrationBean;
    }

    @Bean
    public FilterRegistrationBean DruidStatFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        return filterRegistrationBean;
    }

    /**
     * 数据库链接池
     *
     * @return
     */
    @Bean(initMethod = "init", destroyMethod = "close")
    public DruidDataSource druidDataSource() {
        log.info("获取到的数据库配置信息为：{}", props);
        String driverClass = props.getDriverClass();
        if (StringUtils.isEmpty(driverClass)) {
            log.error("数据库驱动名称为空");
            throw new RuntimeException("数据库驱动名称为空");
        }
        String url = props.getUrl();
        if (StringUtils.isEmpty(url)) {
            log.error("数据库链接为空");
            throw new RuntimeException("数据库链接为空");
        }
        String user = props.getUser();
        if (StringUtils.isEmpty(user)) {
            log.error("数据库用户为空");
            throw new RuntimeException("数据库用户为空");
        }
        String password = props.getPassword();
        if (StringUtils.isEmpty(password)) {
            log.error("数据库密码为空");
            throw new RuntimeException("数据库密码为空");
        }
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(driverClass);
        druidDataSource.setUrl(url);
        druidDataSource.setUsername(user);
        druidDataSource.setPassword(password);
        druidDataSource.setInitialSize(10);
        druidDataSource.setMinIdle(10);
        druidDataSource.setMaxActive(20);
        druidDataSource.setPoolPreparedStatements(true);
        return druidDataSource;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory() {
        try {
            SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
            sqlSessionFactoryBean.setDataSource(druidDataSource());
            sqlSessionFactoryBean.setTypeAliasesPackage("cn.gyouzhe.entity");
            PageHelper pageHelper = new PageHelper();
            Properties props = new Properties();
            props.setProperty("reasonable", "true");
            props.setProperty("supportMethodsArguments", "true");
            props.setProperty("returnPageInfo", "check");
            props.setProperty("params", "count=countSql");
            pageHelper.setProperties(props);
            TypeHandler<?>[] typeHandlers = new TypeHandler[]{
                    new InstantTypeHandler(),
                    new LocalDateTimeTypeHandler(),
                    new LocalDateTypeHandler(),
                    new LocalTimeTypeHandler(),
                    new OffsetDateTimeTypeHandler(),
                    new OffsetTimeTypeHandler(),
                    new ZonedDateTimeTypeHandler()
            };
            sqlSessionFactoryBean.setTypeHandlers(typeHandlers);

            sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageHelper});
//            ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
//            sqlSessionFactoryBean.setMapperLocations(resourcePatternResolver.getResources("classpath:mapper/*.xml"));
            return sqlSessionFactoryBean.getObject();
        } catch (Exception e) {
            log.error("初始化SqlSessionFactory异常", e);
            throw new RuntimeException(e);
        }
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplate() {
        return new SqlSessionTemplate(sqlSessionFactory());
    }

    /**
     * 事物处理
     *
     * @return
     */
    @Bean
    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return new DataSourceTransactionManager(druidDataSource());
    }
}
